/*
 * Copyright 2017 Zhihu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.zhihu.matisse.engine.impl;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.view.View;
import android.widget.ImageView;

import androidx.fragment.app.Fragment;

import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.ViewTarget;
import com.lib.image.R;
import com.lib.image.glide.GlideApp;
import com.zhihu.matisse.engine.BlurTransformation;
import com.zhihu.matisse.engine.ImageEngine;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * {@link ImageEngine} implementation using Glide.
 */


public class GlideEngine implements ImageEngine {

    private boolean checkLowerMemory() {
        long dealLine = 200L * 1024 * 1024;
        return Runtime.getRuntime().maxMemory() <= dealLine;
    }


    @Override
    public void loadCorners(ImageView imageView, String path, int roundCorners, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(path)
                .apply(RequestOptions.bitmapTransform(new RoundedCorners(roundCorners)))
                .into(imageView);
    }

    @Override
    public void loadCorners(ImageView imageView, Bitmap btm, int roundCorners, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(btm)
                .apply(RequestOptions.bitmapTransform(new RoundedCorners(roundCorners)))
                .into(imageView);
    }

    @Override
    public void loadDefault(ImageView imageView, String path, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(path)
                .into(imageView);
    }

    @Override
    public void loadFitCenterImage(ImageView imageView, String url, int width, int height, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        ViewTarget<ImageView, Drawable> into =manager
                .load(url)
                .apply(new RequestOptions().fitCenter())
                .override(width, height)
                .into(imageView);
        //如果低于手机最大内存低于200M，那么策略就是，view被移出内存也清理
        if (checkLowerMemory()) {
            into.clearOnDetach();
        }
    }

    @Override
    public void loadFitCenterImage(ImageView imageView, Bitmap bitmap, int width, int height, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.load(bitmap)
                .apply(new RequestOptions().fitCenter())
                .override(width, height)
                .into(imageView);
    }

    @Override
    public void loadFitCenterImage(ImageView imageView, String url, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.load(url)
                .apply(new RequestOptions()
                        .fitCenter())
                .into(imageView);
    }

    @Override
    public void loadThumbnail(ImageView imageView, String url, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(url)
                .apply(new RequestOptions()
                        .centerCrop())
                .into(imageView);
    }

    @Override
    public void loadThumbnail(ImageView imageView, int resId, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(resId)
                .apply(new RequestOptions()
                        .centerCrop())
                .into(imageView);
    }

    @Override
    public void loadCircle(ImageView imageView, String url, int errorId, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(url)
                .error(errorId)
                .apply(RequestOptions.bitmapTransform(new CircleCrop()))
                .into(imageView);
    }

    @Override
    public void loadCircle(ImageView imageView, String url, int size, int errorId, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(url)
                .error(errorId)
                .apply(RequestOptions.bitmapTransform(new CircleCrop()).override(size, size).circleCrop())
                .into(imageView);
    }

    @Override
    public void loadCircle(ImageView imageView, int resId, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(resId)
                .apply(RequestOptions.bitmapTransform(new CircleCrop()))
                .into(imageView);
    }

    @Override
    public void loadFitCenter(ImageView imageView, String url, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(url)
                .apply(new RequestOptions()
                        .fitCenter())
                .into(imageView);
    }

    @Override
    public void loadThumbnail(int resize, Drawable placeholder, ImageView imageView, Uri uri, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(uri)
                .apply(new RequestOptions()
                        .override(resize, resize)
                        .placeholder(placeholder)
                        .centerCrop())
                .into(imageView);
    }

    @Override
    public void loadGifThumbnail(int resize, Drawable placeholder, ImageView imageView,
                                 Uri uri, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asBitmap() // some .jpeg files are actually gif
                .load(uri)
                .apply(new RequestOptions()
                        .override(resize, resize)
                        .placeholder(placeholder)
                        .centerCrop())
                .into(imageView);
    }

    @Override
    public void loadImage(int resizeX, int resizeY, ImageView imageView, Uri uri, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.load(uri)
                .apply(new RequestOptions()
                        .override(resizeX, resizeY)
                        .priority(Priority.HIGH)
                        .fitCenter())
                .into(imageView);
    }

    @Override
    public void loadGifImage(int resizeX, int resizeY, ImageView imageView, Uri uri, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.asGif()
                .load(uri)
                .apply(new RequestOptions()
                        .override(resizeX, resizeY)
                        .priority(Priority.HIGH)
                        .fitCenter())
                .into(imageView);
    }

    @Override
    public void loadThumbnail(int resize, Drawable placeholder, ImageView imageView, String path, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.load(path)
                .apply(new RequestOptions()
                        .override(resize, resize)
                        .placeholder(placeholder)
                        .centerCrop())
                .into(imageView);
    }

    @Override
    public void loadThumbnailP(int resize, ImageView imageView, String path, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.load(path)
                .apply(new RequestOptions()
                        .override(resize, resize)
                        .placeholder(R.drawable.default_img)
                        .error(R.drawable.default_img)
                        .centerCrop())
                .into(imageView);
    }

    @Override
    public void loadCenterCropImage(ImageView imageView, String url, int width, int height, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.load(url)
                .apply(new RequestOptions()
                        .override(width, height)
                        .centerCrop())
                .into(imageView);
    }

    @Override
    public void loadCenterCropImageP(ImageView imageView, String url, int width, int height, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        if (fragment != null) {
            manager = Glide.with(fragment);
        } else if (activity != null) {
            manager = Glide.with(activity);
        } else if (view != null) {
            manager = Glide.with(view);
        } else {
            manager = Glide.with(context);
        }
        manager.load(url)
                .apply(new RequestOptions()
                        .override(width, height)
                        .placeholder(R.drawable.default_img)
                        .error(R.drawable.default_img))
                .into(imageView);
    }

    @Override
    public void loadBlur(@NotNull ImageView imageView, @Nullable String img, int blur, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        Context ctx;
        if (fragment != null) {
            manager = Glide.with(fragment);
            ctx = fragment.getContext();
            if(ctx != null) {
                ctx = ctx.getApplicationContext();
            }
        } else if (activity != null) {
            manager = Glide.with(activity);
            ctx = activity.getApplicationContext();
        } else if (view != null) {
            manager = Glide.with(view);
            ctx = view.getContext().getApplicationContext();
        } else {
            manager = Glide.with(context);
            ctx = context.getApplicationContext();
        }
        manager.load(img).apply(RequestOptions.bitmapTransform(new BlurTransformation(ctx, 25, blur))).into(imageView);
    }

    @Override
    public void loadBlur(@NotNull ImageView imageView, int resId, int blur, Activity activity, Fragment fragment, View view, Context context) {
        RequestManager manager;
        Context ctx;
        if (fragment != null) {
            manager = Glide.with(fragment);
            ctx = fragment.getContext();
            if(ctx != null) {
                ctx = ctx.getApplicationContext();
            }
        } else if (activity != null) {
            manager = Glide.with(activity);
            ctx = activity.getApplicationContext();
        } else if (view != null) {
            manager = Glide.with(view);
            ctx = view.getContext().getApplicationContext();
        } else {
            manager = Glide.with(context);
            ctx = context.getApplicationContext();
        }
        manager.load(resId).apply(RequestOptions.bitmapTransform(new BlurTransformation(ctx, 25, blur))).into(imageView);
    }

    @Override
    public boolean supportAnimatedGif() {
        return true;
    }

    @Override
    public void clearDiskCache(Context context) {
        Glide.get(context).clearDiskCache();
    }

    @Override
    public void clearMemory(Context context) {
        Glide.get(context).clearMemory();
    }

    @Override
    public void trimMemory(Context context, int level) {
        Glide.get(context).trimMemory(level);
    }

}
